package com.aneliya.mediator;

import java.util.EventObject;

import javax.swing.SwingUtilities;

import com.aneliya.command.loginDialog.CloseLoginDialogCommand;
import com.aneliya.command.loginDialog.LoginUserCommand;
import com.aneliya.command.loginDialog.RegisterUserCommand;
import com.aneliya.framework.mvc.Facade;
import com.aneliya.framework.mvc.controller.MVCEvent;
import com.aneliya.framework.mvc.view.Mediator;
import com.aneliya.model.User;
import com.aneliya.view.ChatWindow;
import com.aneliya.view.LoginDialog;
import com.aneliya.view.LoginDialogListener;

public class LoginDialogMediator extends Mediator {
	public static final String LOGIN_USER_EVENT = "loginUser";
	public static final String REGISTER_USER_EVENT = "registerUser";
	public static final String CLOSE_LOGIN_DIALOG_EVENT = "closeLoginDialog";
	
	private LoginDialog loginDialog;
	
	public LoginDialog getLoginDialog() {
		return loginDialog;
	}
	
	public LoginDialogMediator() throws Exception {
		name = "LoginDialogMediator";
		facade = Facade.getInstance();
		
		initializeCommands();
	}

	private void initializeCommands() throws Exception {
		facade.registerCommand(LOGIN_USER_EVENT, LoginUserCommand.class);
		facade.registerCommand(REGISTER_USER_EVENT, RegisterUserCommand.class);
		facade.registerCommand(CLOSE_LOGIN_DIALOG_EVENT, CloseLoginDialogCommand.class);
	}
	
	public void open() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					initializeLoginDialog();
					loginDialog.setLocationRelativeTo(getChatWindow());
					loginDialog.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public void close() {
		loginDialog.setVisible(false);
	}
	
	private void dispatchCloseLoginDialogEvent() throws InstantiationException, IllegalAccessException {
		facade.dispatchMVCEvent(new MVCEvent(this, CLOSE_LOGIN_DIALOG_EVENT, null));
	}
	
	private void dispatchLoginUserEvent() throws InstantiationException, IllegalAccessException {
		User user = getUser();
		facade.dispatchMVCEvent(new MVCEvent(this, LOGIN_USER_EVENT, user));
	}

	private void dispatchRegisterUserEvent() throws InstantiationException, IllegalAccessException {
		User user = getUser();
		facade.dispatchMVCEvent(new MVCEvent(this, REGISTER_USER_EVENT, user));
	}
	
	private void initializeLoginDialog() throws Exception {
		ChatWindow chatWindow = getChatWindow();
		
		if (loginDialog == null) {
			loginDialog = new LoginDialog(chatWindow);
			initializeLoginDialogListener();
		}
	}

	private void initializeLoginDialogListener() {
		LoginDialogListener listener = new LoginDialogListener() {
			public void dialogClosed(EventObject e) {
				try {
					dispatchCloseLoginDialogEvent();
				} catch (InstantiationException ex) {
					ex.printStackTrace();
				} catch (IllegalAccessException ex) {
					ex.printStackTrace();
				}
			}

			public void userLogged(EventObject e) {
				try {
					dispatchLoginUserEvent();
				} catch (InstantiationException ex) {
					ex.printStackTrace();
				} catch (IllegalAccessException ex) {
					ex.printStackTrace();
				}
			}

			public void userRegistered(EventObject e) {
				try {
					dispatchRegisterUserEvent();
				} catch (InstantiationException ex) {
					ex.printStackTrace();
				} catch (IllegalAccessException ex) {
					ex.printStackTrace();
				}
			}
			
		};
		loginDialog.addLoginDialogListener(listener);
	}

	private ChatWindow getChatWindow() throws Exception {
		ChatWindowMediator chatWindowMediator = (ChatWindowMediator) facade.retrieveMediator("ChatWindowMediator");
		return chatWindowMediator.getChatWindow();
	}
	
	private User getUser() {
		return new User(loginDialog.getUsername(), loginDialog.getPassword());
	}

}
